from django.contrib.auth.models import AbstractUser
from django.db import models


class Area(models.Model):
    '''地区地址表'''

    class AreaLevel(models.IntegerChoices):
        PROVINCE = 1, '省级（省份、直辖市、自治区）'
        CITY = 2, '地级（城市）'
        DISTRICT = 3, '县级（区县）'
        STREET = 4, '乡级（乡镇、街道）'
        VILLAGES = 5, '村级（村委会、居委会）'

    name = models.CharField(db_comment='名称', max_length=64)
    level = models.PositiveSmallIntegerField(db_comment='地区等级', choices=AreaLevel.choices)
    pinyin = models.CharField(db_comment="拼音", max_length=255)
    initial = models.CharField(db_comment="首字母", max_length=20)
    status = models.BooleanField(db_comment="状态", default=True, blank=True)
    sort = models.PositiveSmallIntegerField(db_comment="显示排序", default=34)
    parent = models.ForeignKey(to='self', on_delete=models.DO_NOTHING, db_constraint=False, null=True, blank=True,
                               db_index=True)

    class Meta:
        db_table = 'tb_area'
        db_table_comment = "地区表"
        ordering = ["sort"]


class User(AbstractUser):
    '''系统用户'''

    class Gender(models.IntegerChoices):
        UNKNOWN = 0, '未知'
        MALE = 1, '男'
        FEMALE = 2, '女'
        __empty__ = '未知'

    name = models.CharField(db_comment='用户姓名', max_length=32, blank=True, null=True)
    gender = models.PositiveSmallIntegerField(db_comment='性别', choices=Gender.choices, default=Gender.UNKNOWN,
                                              null=True, blank=True)
    id_card = models.CharField(db_comment='身份证号', max_length=18, blank=True, null=True)
    phone = models.CharField(db_comment='手机号码', max_length=11, blank=True, null=True)
    email = models.EmailField(db_comment='邮箱', null=True, blank=True)
    status = models.BooleanField(db_comment="状态", default=True, blank=True)
    description = models.CharField(db_comment="描述", max_length=255, null=True, blank=True)
    update_time = models.DateTimeField(db_comment="修改时间", auto_now=True, null=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)
    roles = models.ManyToManyField(db_comment='角色', to='Role', blank=True, db_constraint=False)
    posts = models.ManyToManyField(db_comment="关联岗位", to="Post", blank=True, db_constraint=False)
    dept = models.ForeignKey(db_comment="所属部门", to="Dept", on_delete=models.DO_NOTHING, db_constraint=False,
                             null=True, blank=True)

    class Meta(AbstractUser.Meta):
        swappable = 'AUTH_USER_MODEL'
        db_table = 'tb_user'
        db_table_comment = "系统用户表"
        ordering = ['-date_joined']

    REQUIRED_FIELDS = ['phone']

    def __str__(self):
        return self.username

    def get_user_permission(self):
        # 获取用户权限

        # print(
        #     self.roles.filter(name='医生', menus__parent__isnull=False, menus__permission__isnull=False)
        #         .annotate(title=F('menus__title'),permission=F('menus__permission')).values('title', 'permission'))
        # print(set(self.roles.filter(name='医生', menus__parent__isnull=False, menus__permission__isnull=False).values_list( 'menus__permission',flat=True)))

        if self.is_superuser:
            # return set(list(Menu.objects.filter(type=2).values_list('permission', flat=True)))
            return ['*:*']

        return set(
            self.roles.filter(name='医生', menus__parent__isnull=False, menus__permission__isnull=False).values_list(
                'menus__permission', flat=True))

    def get_roles(self):
        return self.roles.values_list('name', flat=True)


class Role(models.Model):
    """
    角色
    """
    name = models.CharField(db_comment='名称', max_length=32, unique=True)
    key = models.CharField(db_comment="角色编码", max_length=64, null=True, blank=True)
    sort = models.PositiveSmallIntegerField(db_comment="显示排序", default=1)
    status = models.BooleanField(db_comment="状态", default=True, blank=True)
    description = models.CharField(db_comment="描述", max_length=255, null=True, blank=True)
    update_time = models.DateTimeField(db_comment="修改时间", auto_now=True, null=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)
    menus = models.ManyToManyField(db_comment='关联菜单', to='Menu', blank=True, db_constraint=False)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tb_role'
        db_table_comment = '角色表'
        ordering = ["sort"]


class Menu(models.Model):
    class MenuType(models.IntegerChoices):
        CATALOG = 0, '目录'
        MENU = 1, '菜单'
        PERMISSON = 2, '权限'

    icon = models.CharField(db_comment="菜单图标", max_length=64, null=True, blank=True)
    title = models.CharField(db_comment="菜单名称", max_length=64)
    is_link = models.BooleanField(db_comment="是否外链", default=False)
    path = models.CharField(db_comment="路由地址", max_length=128, null=True, blank=True)
    component = models.CharField(db_comment="组件路径", max_length=128, null=True, blank=True)
    name = models.CharField(db_comment="路由名称", max_length=64, null=True, blank=True)
    permission = models.CharField(db_comment="权限值", max_length=128, null=True, blank=True)
    api = models.CharField(db_comment="接口地址", max_length=255, null=True, blank=True)
    cache = models.BooleanField(db_comment="是否页面缓存", default=False, blank=True)
    hidden = models.BooleanField(db_comment="侧边栏中是否显示", default=False, blank=True)
    status = models.BooleanField(db_comment="状态", default=True, blank=True)
    sort = models.PositiveSmallIntegerField(db_comment="显示排序", default=1, null=True, blank=True)
    menu_type = models.PositiveSmallIntegerField(db_comment='菜单类型', choices=MenuType.choices,
                                                 default=MenuType.CATALOG, null=True, blank=True)
    description = models.CharField(db_comment="描述", max_length=255, null=True, blank=True)
    update_time = models.DateTimeField(db_comment="修改时间", auto_now=True, null=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)
    parent = models.ForeignKey(db_comment="上级菜单", to="Menu", on_delete=models.CASCADE, null=True, blank=True,
                               db_constraint=False)

    class Meta:
        db_table = "tb_menu"
        db_table_comment = "菜单表"
        ordering = ["sort"]

    def __str__(self):
        return self.title


class Dept(models.Model):
    class DepartmentType(models.IntegerChoices):
        SCHOOL = 0, '学校'
        MEDICAL_INSTITUTION = 1, '医疗机构'
        GOVERNMENT_SECTOR = 2, '政府部门'

    name = models.CharField(db_comment="部门名称", max_length=64)
    key = models.CharField(db_comment="部门编码", max_length=64, null=True, blank=True)
    owner = models.CharField(db_comment="负责人", max_length=32, null=True, blank=True)
    phone = models.CharField(db_comment="联系电话", max_length=32, null=True, blank=True)
    email = models.EmailField(db_comment="邮箱", max_length=32, null=True, blank=True)
    dept_type = models.PositiveSmallIntegerField(db_comment='部门类型', choices=DepartmentType.choices, null=True,
                                                 blank=True)

    province = models.ForeignKey(db_comment='省级（省份、直辖市、自治区）', to='system.Area', on_delete=models.DO_NOTHING,
                                 related_name='dept_province', db_constraint=False, null=True, blank=True)
    city = models.ForeignKey(db_comment='地级（城市）', to='system.Area', on_delete=models.DO_NOTHING,
                             related_name='dept_city', db_constraint=False, null=True, blank=True)
    district = models.ForeignKey(db_comment='县级（区县）', to='system.Area', on_delete=models.DO_NOTHING,
                                 related_name='dept_district', db_constraint=False, null=True, blank=True)
    street = models.ForeignKey(db_comment='乡级（乡镇、街道）', to='system.Area', on_delete=models.DO_NOTHING,
                               related_name='dept_street', db_constraint=False, null=True, blank=True)
    place = models.CharField(db_comment='具体住址', max_length=64, blank=True, null=True)

    status = models.BooleanField(db_comment="状态", default=True, blank=True)
    sort = models.PositiveSmallIntegerField(db_comment="显示排序", default=1)
    description = models.CharField(db_comment="描述", max_length=255, null=True, blank=True)
    update_time = models.DateTimeField(db_comment="修改时间", auto_now=True, null=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = "tb_dept"
        db_table_comment = "部门表"
        ordering = ["sort"]


class Post(models.Model):
    name = models.CharField(db_comment="岗位名称", null=False, max_length=64)
    key = models.CharField(db_comment="岗位编码", max_length=32, null=True, blank=True)
    status = models.BooleanField(db_comment="状态", default=True, blank=True)
    sort = models.PositiveSmallIntegerField(db_comment="岗位顺序", default=1)
    description = models.CharField(db_comment="描述", max_length=255, null=True, blank=True)
    update_time = models.DateTimeField(db_comment="修改时间", auto_now=True, null=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)

    class Meta:
        db_table = "tb_post"
        db_table_comment = "岗位表"
        ordering = ["sort"]

    def __str__(self):
        return self.name


class OperationLog(models.Model):
    request_modular = models.CharField(db_comment="请求模块", max_length=64, null=True, blank=True)
    request_path = models.CharField(db_comment="请求地址", max_length=400, null=True, blank=True)
    request_body = models.TextField(db_comment="请求参数", null=True, blank=True)
    request_method = models.CharField(db_comment="请求方式", max_length=8, null=True, blank=True)
    request_msg = models.TextField(db_comment="操作说明", null=True, blank=True)
    request_ip = models.CharField(db_comment="请求ip地址", max_length=32, null=True, blank=True)
    request_browser = models.CharField(db_comment="请求浏览器", max_length=64, null=True, blank=True)
    response_code = models.CharField(db_comment="响应状态码", max_length=32, null=True, blank=True)
    request_os = models.CharField(db_comment="操作系统", max_length=64, null=True, blank=True)
    response_content = models.TextField(db_comment="返回信息", null=True, blank=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)
    creator = models.ForeignKey(db_comment='创建人', to='User', on_delete=models.SET_NULL, null=True,
                                db_constraint=False)

    class Meta:
        db_table = "tb_operation_log"
        db_table_comment = "操作日志表"
        ordering = ["-create_time"]


class LoginLog(models.Model):
    LOGIN_TYPE_CHOICES = ((1, "普通登录"), (2, "微信扫码登录"),)
    username = models.CharField(db_comment="登录用户名", max_length=32, null=True, blank=True)
    ip = models.CharField(db_comment="登录ip", max_length=32, null=True, blank=True)
    agent = models.TextField(db_comment="agent信息", null=True, blank=True)
    browser = models.CharField(db_comment="浏览器名", max_length=255, null=True, blank=True)
    os = models.CharField(db_comment="操作系统", max_length=255, null=True, blank=True)
    continent = models.CharField(db_comment="州", max_length=50, null=True, blank=True)
    country = models.CharField(db_comment="国家", max_length=50, null=True, blank=True)
    province = models.CharField(db_comment="省份", max_length=50, null=True, blank=True)
    city = models.CharField(db_comment="城市", max_length=50, null=True, blank=True)
    district = models.CharField(db_comment="县区", max_length=50, null=True, blank=True)
    isp = models.CharField(db_comment="运营商", max_length=50, null=True, blank=True)
    area_code = models.CharField(db_comment="区域代码", max_length=50, null=True, blank=True)
    country_english = models.CharField(db_comment="英文全称", max_length=50, null=True, blank=True)
    country_code = models.CharField(db_comment="简称", max_length=50, null=True, blank=True)
    longitude = models.CharField(db_comment="经度", max_length=50, null=True, blank=True)
    latitude = models.CharField(db_comment="纬度", max_length=50, null=True, blank=True)
    login_type = models.PositiveSmallIntegerField(db_comment="登录类型", default=1, choices=LOGIN_TYPE_CHOICES)

    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)
    creator = models.ForeignKey(db_comment='创建人', to='User', on_delete=models.SET_NULL, null=True,
                                db_constraint=False)

    class Meta:
        db_table = "tb_login_log"
        db_table_comment = "登录日志表"
        ordering = ["-create_time"]


class Dictionary(models.Model):
    TYPE_LIST = (
        (0, "text"),
        (1, "number"),
        (2, "date"),
        (3, "datetime"),
        (4, "time"),
        (5, "files"),
        (6, "boolean"),
        (7, "images"),
    )
    label = models.CharField(max_length=128, blank=True, null=True, db_comment="字典名称")
    value = models.CharField(max_length=256, blank=True, null=True, db_comment="字典值")
    parent = models.ForeignKey(
        to="self",
        related_name="sublist",
        db_constraint=False,
        on_delete=models.PROTECT,
        blank=True,
        null=True,
        db_comment="父级",
    )
    type = models.IntegerField(db_comment="数据值类型", choices=TYPE_LIST, default=0, )
    color = models.CharField(db_comment="颜色", max_length=32, blank=True, null=True)
    is_value = models.BooleanField(db_comment="是否为value值", default=False)
    status = models.BooleanField(db_comment="状态", default=True)
    sort = models.IntegerField(db_comment="显示排序", default=1, null=True, blank=True)
    description = models.CharField(db_comment="描述", max_length=255, null=True, blank=True)
    update_time = models.DateTimeField(db_comment="修改时间", auto_now=True, null=True)
    create_time = models.DateTimeField(db_comment="创建时间", auto_now_add=True, null=True)

    class Meta:
        db_table = "tb_dictionary"
        db_table_comment = "字典表"
        ordering = ["sort"]
